package eteam.aps.common.helper;

import cn.hutool.core.io.FileUtil;
import cn.hutool.json.JSONConfig;
import com.fasterxml.jackson.databind.ObjectMapper;
import eteam.aps.common.entity.ParentEntity;

import java.lang.reflect.Field;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 帮助类
 */
public class Helper {

    public static final ObjectMapper JACKSON_OBJECT_MAPPER = new ObjectMapper();

    public static final JSONConfig JSON_CONFIG = new JSONConfig();

    static {
        JSON_CONFIG.setIgnoreNullValue(false);
    }

    /**
     * 默认 填充字段 内码、审核状态、创建人、创建时间、修改人、修改时间
     */


    /**
     * 判断对象中属性值是否全为空
     *
     * @param object: 待检查对象
     * @return: 是否为空，true为空对象
     */
    public static boolean checkObjAllFieldsIsNull(Object object) {
        if (null == object) {
            return true;
        }
        try {
            for (Field f : object.getClass().getDeclaredFields()) {
                f.setAccessible(true);
                if (f.get(object) != null && isNotEmpty(f.get(object).toString())) {
                    return false;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return true;
    }

    /**
     * 获取UUid---使用雪花算法
     *
     * @return 返回id
     */
    public static String GetId() {
        return UUID.randomUUID().toString().trim().replaceAll("-", "");
    }

    /**
     * 字符串 是 空白
     *
     * @param str
     * @return true 字符串 是 空白
     */
    public static boolean isEmpty(String str) {
        if (str == null) {
            return true;
        }
        return str.trim().isEmpty();
    }

    public static boolean isNotEmpty(String str) {
        return !isEmpty(str);
    }

    public static String likeSql(String str) {
        if (str == null || (str = str.trim()).isEmpty()) {
            throw new IllegalArgumentException("参数值是空");
        }
        return "%" + str + "%";
    }

    /**
     * @param str
     * @return null 如果是空白
     */
    public static String trim(String str) {
        if (str == null || (str = str.trim()).isEmpty()) {
            return null;
        }
        return str;
    }

    /**
     * 取 正整数
     *
     * @param arg
     * @param defauleVal >=1
     * @return
     */
    public static Integer valuePositive(Integer arg, int defauleVal) {
        if (defauleVal < 1) {
            throw new IllegalArgumentException("必须>=1");
        }

        if (arg == null || arg.intValue() < 1) {
            return Integer.valueOf(defauleVal);
        }
        return arg;
    }

    /**
     * 拼接redis 键值对
     *
     * @param prefix 前缀
     * @param suffix 后缀
     * @return key
     */
    public static String keyGe(String prefix, String suffix) {
        return prefix + "::" + suffix;
    }

    public static <T extends ParentEntity> void setDefaultAddValue(T target, String loginId) {
        if (target == null) return;
        LocalDateTime now = LocalDateTime.now();
        target.setfId(GetId());
        target.setfState(ParentEntity.FSTATE_DRAFT);
        target.setfCreateUserId(loginId);
        target.setfCreatorTime(now);
        target.setfLastModifyUserId(loginId);
        target.setfLastModifyTime(now);
    }

    /**
     * 判断是否符合指定的正则表达式
     *
     * @param context 内容
     * @param reg     正则表达式
     * @return 是否符合正则表达式
     */
    public static boolean isPattern(String context, String reg) {
        Pattern compile = Pattern.compile(reg);
        Matcher matcher = compile.matcher(context);
        return matcher.find();
    }

    /**
     * 判断是否不符合指定的正则表达式
     *
     * @param context 内容
     * @param reg     正则表达式
     * @return 是否符合正则表达式
     */
    public static boolean isNotPattern(String context, String reg) {
        return !isPattern(context, reg);
    }

    /**
     * 填充字符串
     *
     * @param num 数字
     * @param len 固定长度 不够前面补0
     * @return 序号
     */
    public static String fillNum(int num, int len) {
        return String.format("%0" + len + "d", num);
    }

    /**
     * 将空字符串 填充为null
     *
     * @param target 对象
     */
    public static void setEmptyWithNull(Object target) {
        try {
            Class<?> clazz = target.getClass();
            for (Field field : clazz.getDeclaredFields()) {
                field.setAccessible(true);
                if (field.getType() == String.class) {
                    if (isEmpty((String) field.get(target))) {
                        field.set(target, null);
                    }
                }
            }
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }

    public static String filterStrEng(String str) {
        return str.replaceAll("[a-z|]+", "");
    }


    // 换行
    private static final String NEWLINE = System.getProperty("line.separator");

    // 分隔符
    private static final String SEPARATOR = "====================";

    // 日期格式化
    private static final SimpleDateFormat FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    /**
     * 日志记录
     *
     * @param req 请求数据
     * @param res 响应数据
     * @param st  开始时间
     */
    public static void loadLog(String fileName, String title, String req, String res, long st, boolean stack) {
        StringBuilder log = new StringBuilder();
        // 结束时间
        long ed = System.currentTimeMillis();
        String end = FORMAT.format(new Date(ed));
        // 开始时间
        String start = FORMAT.format(new Date(st));
        StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
        // 获取方法的调用者
        StackTraceElement element = stackTrace[3];
        log.append(SEPARATOR).append(title).append("开始时间：").append(start).append(SEPARATOR).append(NEWLINE);
        if (stack) log.append("调用方法：").append(element.getClassName()).append(".")
                .append(element.getMethodName()).append("\tLineNumber：")
                .append(element.getLineNumber()).append(NEWLINE);
        if (Helper.isNotEmpty(req))
            log.append(SEPARATOR).append("请求体为：").append(SEPARATOR).append(NEWLINE).append(req).append(NEWLINE);
        if (Helper.isNotEmpty(res))
            log.append(SEPARATOR).append("响应体为：").append(SEPARATOR).append(NEWLINE).append(res).append(NEWLINE);
        log.append(SEPARATOR).append("结束时间：").append(end).append("\t")
                .append("共花费：").append((ed - st)).append("ms").append(SEPARATOR)
                .append(NEWLINE).append(NEWLINE);
        String file = "D:\\Java\\project\\logs\\u8\\" + fileName + start.substring(0, 10) + ".log";
        FileUtil.appendString(log.toString(), file, StandardCharsets.UTF_8);
    }

    /**
     * 日志记录
     *
     * @param req 请求数据
     * @param res 响应数据
     * @param st  开始时间
     */
    public static void loadLog(String title, String req, String res, long st, boolean stack) {
        StringBuilder log = new StringBuilder();
        // 结束时间
        long ed = System.currentTimeMillis();
        String end = FORMAT.format(new Date(ed));
        // 开始时间
        String start = FORMAT.format(new Date(st));
        StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
        // 获取方法的调用者
        StackTraceElement element = stackTrace[3];
        log.append(SEPARATOR).append(title).append("开始时间：").append(start).append(SEPARATOR).append(NEWLINE);
        if (stack) log.append("调用方法：").append(element.getClassName()).append(".")
                .append(element.getMethodName()).append("\tLineNumber：")
                .append(element.getLineNumber()).append(NEWLINE);
        if (Helper.isNotEmpty(req))
            log.append(SEPARATOR).append("请求体为：").append(SEPARATOR).append(NEWLINE).append(req).append(NEWLINE);
        if (Helper.isNotEmpty(res))
            log.append(SEPARATOR).append("响应体为：").append(SEPARATOR).append(NEWLINE).append(res).append(NEWLINE);
        log.append(SEPARATOR).append("结束时间：").append(end).append("\t")
                .append("共花费：").append((ed - st)).append("ms").append(SEPARATOR)
                .append(NEWLINE).append(NEWLINE);
        String file = "D:\\Java\\project\\logs\\u8\\" + start.substring(0, 10) + ".log";
        FileUtil.appendString(log.toString(), file, StandardCharsets.UTF_8);
    }

    /**
     * 日志记录
     *
     * @param st 开始时间
     */
    public static void loadLog(long st, String url) {
        StringBuilder sb = new StringBuilder();
        // 开始时间
        String start = FORMAT.format(new Date(st));
        sb.append(start).append("\t调用接口为：").append(url).append(NEWLINE);
        String file = "D:\\Java\\project\\logs\\u8\\接口调用" + start.substring(0, 10) + ".log";
        FileUtil.appendString(sb.toString(), file, StandardCharsets.UTF_8);
    }

}
